home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #2 / Monster Media No. 2 (Monster Media)(1994).ISO / prog_gen / gcoope10.zip / COLLECT.C < prev    next >
Text File  |  1994-07-22  |  6KB  |  224 lines

  1. /*
  2.  
  3.     Collection class definition for GCOOPE 1.0
  4.  
  5.         by Brian Lee Price
  6.  
  7.     Released as Public Domain   July, 1994.
  8.  
  9.     Compatible with experimental strong typing option.
  10.  
  11.     While not the best example of object oriented programming,
  12.     this class does demonstrate one method of encapsulating a
  13.     pre-defined set of functions and structures into an object
  14.     class definition.
  15.  
  16.     This class maintains a contiguous section of memory divided into
  17.     fixed size slots, it makes no presumptions about the data entered
  18.     into the slots.  When a slot is removed via the rmvUnit generic,
  19.     it will be cleared to all zeros.  A firstFree index is maintained
  20.     which is used to find the index value to return when a call is
  21.     made via the addUnit generic.  The list may be compacted by the
  22.     compact generic, this call requires a boolean parm 'sorted'.  When
  23.     this parm is true the routine will 'squeeze' the list and remove
  24.     the empty slots, otherwise the routine will just reallocate if
  25.     enough empty slots exist at the end of the list to justify it.
  26.  
  27.     The real value of this class is its suitability for ordered or
  28.     unordered dynamic list maintenance and its reduction of memory
  29.     fragmentation by always resizing to a multiple of MIN_LIST_ADD
  30.     slots.  An inheritor of this class can manage lists which change
  31.     in size from a minimum of MIN_LIST_ADD elements to a maximum of
  32.     just under 64K in total size.  The three kernel functions used by
  33.     this class form the core of the kernel's odbms.
  34.  
  35. */
  36.  
  37. #define CLASS Collection
  38.  
  39. #define _INTERNAL_
  40.  
  41. #include "gcoope10.h"
  42.  
  43. #include <mem.h>
  44.  
  45. object CLASS;
  46.  
  47. extern object Unsigned;
  48.  
  49. /*
  50.  
  51.     This class uses a portion of the internal PCOOPE kernel to save code:
  52.  
  53.     -#define DYNLIST_STRU word elemSize,firstFree,maxElems;void * listPtr
  54.  
  55.     -#define MAX_BLOCK_SIZE (65523L)
  56.  
  57.     -#define MIN_LIST_ADD 16
  58.  
  59.     the following functions are defined in listmgr.c
  60.  
  61.     int     addItem(void *listPtr, int elemSize);
  62.     int     rmvItem(void *listPtr, int elemNdx);
  63.     stat     compactList(void *listAdr, boolean sorted);
  64.  
  65. */
  66.  
  67. typedef struct {
  68.     DYNLIST_STRU;
  69.     } instVars;
  70.  
  71. USEGEN(addUnit);
  72. USEGEN(rmvUnit);
  73. USEGEN(getUnit);
  74. USEGEN(valueOf);
  75. USEGEN(sizeOf);
  76. USEGEN(addressOf);
  77. USEGEN(reSize);
  78. USEGEN(changeVal);
  79. USEGEN(compact);
  80. USEGEN(numElems);
  81.  
  82.  
  83. cmethod object m4New(object instance, word elemSize)
  84. {
  85. instVars * ivptr;
  86.  
  87. if(NULL==(ivptr=makeInst(&instance))) return 0;
  88. ivptr->elemSize=elemSize;
  89. ivptr->listPtr=NULL;
  90. g(New)(ST(Unsigned),0);
  91. return instance;
  92. }
  93.  
  94.  
  95. /* returns the offset of the newly created slot */
  96.  
  97. imethod int m4addUnit(object instance, void * newUnit)
  98. {
  99. instVars *     ivptr;
  100. char *        newSlot;
  101. int        offset=-1;
  102.  
  103. if(NULL==(ivptr=getIVptr(instance))) goto end;
  104. if((offset=addItem(ivptr->listPtr, ivptr->elemSize))<0) goto end;
  105. if(newUnit)
  106.     {
  107.     newSlot=ivptr->listPtr;
  108.     newSlot+= ivptr->elemSize * offset;
  109.     memcpy(newSlot, newUnit, ivptr->elemSize);
  110.     }
  111. g(GEN(changeVal))(ST(Unsigned),
  112.     (unsigned short) ((UNSGNDRV)g)(GEN(valueOf))(instance)+1);
  113.  
  114. end:
  115. return offset;
  116. }
  117.  
  118.  
  119. imethod object m4rmvUnit(object instance, int index)
  120. {
  121. instVars *    ivptr;
  122.  
  123. if((NULL==(ivptr=getIVptr(instance))) ||
  124.     (rmvItem(ivptr->listPtr, index)<0)) return FUNCFAIL;
  125. g(GEN(changeVal))(ST(Unsigned),
  126.     (unsigned short) ((UNSGNDRV)g)(GEN(valueOf))(instance)+1);
  127.  
  128. return FUNCOKAY;
  129. }
  130.  
  131.  
  132. imethod void * m4getUnit(object instance, int index)
  133. {
  134. instVars *    ivptr;
  135.  
  136. if((NULL==(ivptr=getIVptr(instance))) ||
  137.     (index<0) || (index>ivptr->maxElems)) return NULL;
  138. else return (((char *) (ivptr->listPtr))+ index * ivptr->elemSize);
  139. }
  140.  
  141.  
  142. imethod word m4sizeOf(object instance)
  143. {
  144. return ((instVars *) getIVptr(instance))->elemSize;
  145. }
  146.  
  147.  
  148. imethod void * m4addressOf(object instance)
  149. {
  150. return ((instVars *) getIVptr(instance))->listPtr;
  151. }
  152.  
  153.  
  154. imethod object m4reSize(object instance, unsigned short newNumElems)
  155. {
  156. instVars *      ivptr;
  157. int        newSize;
  158. void *        temp;
  159.  
  160. if(NULL==(ivptr=getIVptr(instance))
  161.     || NULL==ivptr->listPtr) return FUNCFAIL;
  162. newSize=newNumElems;
  163. newNumElems/=MIN_LIST_ADD;
  164. if(newSize % MIN_LIST_ADD) newNumElems++;
  165. newNumElems*=MIN_LIST_ADD;
  166. newSize = ivptr->elemSize * newNumElems;
  167. if(newSize < ivptr->maxElems)
  168.     {
  169.     ivptr->listPtr=s_realloc(ivptr->listPtr, newSize);
  170.     if(ivptr->firstFree>newNumElems) ivptr->firstFree=newNumElems;
  171.     if(g(GEN(valueOf))(Unsigned) > newNumElems)
  172.     g(GEN(changeVal))(ST(Unsigned), newNumElems);
  173.     }
  174. else
  175.     {
  176.     temp = s_calloc(1, newSize);
  177.     memcpy(temp, ivptr->listPtr, ivptr->maxElems);
  178.     s_free(ivptr->listPtr);
  179.     ivptr->listPtr=temp;
  180.     }
  181. ivptr->maxElems=newNumElems;
  182. return FUNCOKAY;
  183. }
  184.  
  185.  
  186. imethod object m4compact(object instance, boolean sorted)
  187. {
  188. instVars *    ivptr;
  189.  
  190. if(NULL==(ivptr=getIVptr(instance))
  191.     || NULL==ivptr->listPtr) return FUNCFAIL;
  192. return compactList(ivptr->listPtr, sorted);
  193. }
  194.  
  195.  
  196. cmethod object m4Kill(object instance)
  197. {
  198. s_free(((instVars *) getIVptr(instance))->listPtr);
  199. g(Kill)(Object, instance);
  200. return instance;
  201. }
  202.  
  203.  
  204. CLASS_INSTALL
  205. {
  206. if(END==(CLASS=g(New)(Class, 0, sizeof(instVars), Unsigned, END))) goto err;
  207. if(addGMthd(CLASS, New, (method) m4New)) goto err;
  208. if(addGMthd(CLASS, Kill, (method) m4Kill)) goto err;
  209. if(addGMthd(CLASS, GEN(addUnit), (method) m4addUnit)) goto err;
  210. if(addGMthd(CLASS, GEN(rmvUnit), (method) m4rmvUnit)) goto err;
  211. if(addGMthd(CLASS, GEN(getUnit), (method) m4getUnit)) goto err;
  212. if(rmvGMthd(CLASS, GEN(changeVal))) goto err;
  213. if(addGMthd(CLASS, GEN(sizeOf), (method) m4sizeOf)) goto err;
  214. if(addGMthd(CLASS, GEN(addressOf), (method) m4addressOf)) goto err;
  215. if(addGMthd(CLASS, GEN(reSize), (method) m4reSize)) goto err;
  216. if(addGMthd(CLASS, GEN(compact), (method) m4compact)) goto err;
  217. if(RENGM(valueOf, Unsigned, numElems)) goto err;
  218. return FUNCOKAY;
  219.  
  220. err:
  221. return FUNCFAIL;
  222. }
  223.  
  224.